import requests
import json
import time
from typing import List, Optional, Dict, Any
from .logger import request_logger

class IntentDetector:
    """
    意图检测器，用于判断用户查询是否需要联网搜索
    使用 Qwen2.5-72b-instruct 大模型进行意图识别
    """
    
    def __init__(self, 
                 model_name: str = "krith/qwen2.5-72b-instruct:IQ1_M",  # 恢复原始模型
                 ollama_base_url: str = "http://localhost:11434",
                 timeout: int = 10):  # 设置超时为10秒
        """
        初始化意图检测器
        
        参数:
            model_name: Ollama上的模型名称，使用原始的Qwen2.5-72b模型
            ollama_base_url: Ollama服务的基础URL
            timeout: 请求超时时间（秒）
        """
        self.model_name = model_name
        self.ollama_base_url = ollama_base_url
        self.api_endpoint = f"{ollama_base_url}/api/generate"
        self.timeout = timeout
        
        # 意图检测提示模板
        self.INTENT_PROMPT = """现在需要你根据当前用户的请求来判断是否需要联网来回答此请求。如果需要联网就回答"是"，否则回答"否"。

【当前问题】
{query}

只回答"是"或"否"!"""
    
    def _call_ollama(self, prompt: str, max_tokens: int = 1) -> Optional[str]:
        """
        调用Ollama API进行意图检测，使用简单单次请求
        
        参数:
            prompt: 发送给模型的提示
            max_tokens: 最大生成token数
            
        返回:
            模型的回复，失败或超时则返回None
        """
        payload = {
            "model": self.model_name,
            "prompt": prompt,
            "stream": False,
            "temperature": 0.1,  # 低温度保证输出稳定
            "max_tokens": max_tokens,  # 限制只生成一个token
            "top_p": 0.95
        }
        
        request_logger.log("尝试调用Ollama进行意图检测", level="debug", data={
            "model": self.model_name,
            "timeout": self.timeout
        })
        
        try:
            print(f"调用Ollama API进行意图检测 (超时: {self.timeout}秒)...")
            
            start_time = time.time()
            response = requests.post(
                self.api_endpoint, 
                json=payload, 
                timeout=self.timeout  # 使用较短的超时时间
            )
            elapsed_time = time.time() - start_time
            
            if response.status_code == 200:
                result = response.json()
                request_logger.log("Ollama意图检测调用成功", level="debug", data={
                    "elapsed_time": f"{elapsed_time:.2f}秒"
                })
                print(f"Ollama API调用成功，耗时：{elapsed_time:.2f}秒")
                return result.get('response', '')
            else:
                error_msg = f"Ollama意图检测调用失败: 状态码 {response.status_code}"
                request_logger.log(error_msg, level="warning")
                print(error_msg)
                return None
        except requests.exceptions.Timeout:
            error_msg = f"Ollama API请求超时，当前超时设置: {self.timeout}秒"
            request_logger.log(error_msg, level="warning")
            print(error_msg)
            return None
        except Exception as e:
            error_msg = f"Ollama意图检测调用异常: {str(e)}"
            request_logger.log(error_msg, level="warning")
            print(error_msg)
            return None
    
    def detect_web_search_intent(self, query: str, history_messages: List[Dict[str, str]] = None) -> bool:
        """
        检测用户查询是否需要联网搜索，简化版本
        如果超时或失败，默认返回True（需要联网）
        
        参数:
            query: 用户当前查询
            history_messages: 历史对话消息（当前未使用）
            
        返回:
            True表示需要联网，False表示不需要
        """
        # 简化提示，只使用查询，不使用历史消息
        prompt = self.INTENT_PROMPT.format(query=query)
        
        request_logger.log("开始意图检测", data={"query": query})
        print(f"\n==== 开始意图检测 ====")
        print(f"当前查询: '{query}'")
        
        # 只尝试一次，如果失败则默认为需要联网
        response = self._call_ollama(prompt)
        
        if not response:
            print("意图检测无响应或超时，默认采用联网搜索")
            request_logger.log("意图检测超时，默认使用联网搜索", level="info")
            return True
            
        # 标准化响应
        normalized_response = response.lower().strip()
        print(f"意图检测响应: '{normalized_response}'")
        
        # 检查是否符合规范输出
        if "否" in normalized_response:
            intent_result = False
            print("意图检测结果: 无需联网")
        else:
            # 不符合规范或包含"是"，都默认需要联网
            intent_result = True
            print("意图检测结果: 需要联网")
        
        request_logger.log("意图检测完成", data={"需要联网": intent_result})
        print(f"==== 意图检测完成 ====\n")
        
        return intent_result


# 全局实例，使用指定模型和超时时间
intent_detector = IntentDetector(
    model_name="krith/qwen2.5-72b-instruct:IQ1_M",  # 使用原始模型
    timeout=13  # 13秒超时
) 